package com.jrx.anytxn.transaction.service.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.entity.PrInterestTable;
import com.jrx.anytxn.param.entity.PrPenaltyRateTable;
import com.jrx.anytxn.param.entity.PrWaiveInterestTable;
import com.jrx.anytxn.param.service.product.IInterestTableService;
import com.jrx.anytxn.param.service.product.IPrPenaltyRateTableService;
import com.jrx.anytxn.param.service.product.IPrWaiveInterestTableService;
import com.jrx.anytxn.transaction.bean.CastAccountTransactionBean;
import com.jrx.anytxn.transaction.bean.DealIntrBean;
import com.jrx.anytxn.transaction.bean.IntrAccuBean;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.*;
import com.jrx.anytxn.transaction.service.IAccountService;
import com.jrx.anytxn.transaction.service.IGlInterfaceService;
import com.jrx.anytxn.transaction.service.IInterestCalculateService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 每日计息处理
 *
 * @author cbd
 */
@Service
public class InterestCalculateServiceImpl implements IInterestCalculateService {

    private static final Logger logger = LoggerFactory.getLogger(InterestCalculateServiceImpl.class);

    @Autowired
    private IAccountService accountService;
    @Autowired
    private IGlInterfaceService glInterfaceService;
    @Autowired
    private ISegmentService segmentService;
    @Autowired
    private IPrPenaltyRateTableService penaltyRateTableService;
    @Autowired
    private IInterestTableService interestTableService;
    @Autowired
    private IPrWaiveInterestTableService prWaiveInterestTableService;

    /**
     * 每日计息处理
     * 以单个计息账户为基础，计算利息，并记录到计息账户上
     *
     * @param dealIntrBean
     */
    @Override
    public IntrAccuBean calculateInterest(DealIntrBean dealIntrBean) throws TxnException {

        Date accruDay = dealIntrBean.getAccruDay();
        Date businessDate = dealIntrBean.getBusinessDate();
        AmInterestAccrualInfo interestAccrualInfo = dealIntrBean.getAccuAcct();
        logger.debug("账户开始每日计息id:{},accountId:{}", interestAccrualInfo.getId(), interestAccrualInfo.getAccountId());
        String type = interestAccrualInfo.getAccountType();

        IntrAccuBean intrAccuBean = new IntrAccuBean();
        AmInterestAccrualInfo updateInterestAccrualInfo = new AmInterestAccrualInfo();
        updateInterestAccrualInfo.setId(interestAccrualInfo.getId());
        updateInterestAccrualInfo.setCustomerId(interestAccrualInfo.getCustomerId());
        updateInterestAccrualInfo.setTenantId(interestAccrualInfo.getTenantId());

        Date accruFromDate = interestAccrualInfo.getAccrualNewFromDate();//累计利息开始日期
        Date accruToDate = interestAccrualInfo.getAccrualNewToDate();//累计利息结束日期
        Date intrStartDate = interestAccrualInfo.getAccrualStartDate();//交易起息日  开始计息日期
        //罚息计提 复利计提
        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(type) || TransBizConstant.INTEREST_ACCRUAL_TYPE_20.equals(type)) {

            if (accruDay.compareTo(intrStartDate) >= 0) {
                //间隔日期
                int elapseDays;

                Date fromDate;    //开始日期
                Date toDate;    //结束日期

                if (accruToDate == null) {//首次计息
                    fromDate = accruFromDate;
                    toDate = accruDay;
                } else {//除首次之后每日计息
                    fromDate = accruToDate;
                    toDate = accruDay;
                }
                elapseDays = DateUtils.getDiffDays(fromDate, toDate);
                if (elapseDays <= 0) {
                    return null;
                }
                BigDecimal interest;

                interest = this.penInterestCalculation(interestAccrualInfo, elapseDays);

                int totalAccruDays = interestAccrualInfo.getAccrualTotalAccruDays() + elapseDays;
                updateInterestAccrualInfo.setAccrualNewFromDate(fromDate);
                updateInterestAccrualInfo.setAccrualNewToDate(toDate);
                updateInterestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                updateInterestAccrualInfo.setAccrualNewDays(elapseDays);
                updateInterestAccrualInfo.setAccrualNewInterest(interest);
                //计算调整后利息 = 当日计提金额+上日调整金额
                BigDecimal dailyAdjustAmt = interestAccrualInfo.getAccrualDailyAdjustment();
                if (dailyAdjustAmt == null) {
                    dailyAdjustAmt = BigDecimal.ZERO;
                }
                BigDecimal afterAdjustAmt = interest.add(dailyAdjustAmt);
                //计算当日计提金额(保留两位小数)
                BigDecimal provision = afterAdjustAmt.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);

                //计算当日调整 = 每日调整后累计-每日计提
                BigDecimal adjustAmt = afterAdjustAmt.subtract(provision);

                provision = provision.add(interestAccrualInfo.getProvisionalAccrualInterest());
                //利息总金额
                BigDecimal totalAccruIntr = interestAccrualInfo.getAccrualTotalAccruInterest().add(provision).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                updateInterestAccrualInfo.setAccrualTotalAccruInterest(totalAccruIntr);
                updateInterestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                updateInterestAccrualInfo.setAccrualDailyProvision(provision);
                updateInterestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);
                updateInterestAccrualInfo.setProvisionalAccrualInterest(BigDecimal.ZERO);

                interestAccrualInfo.setAccrualTotalAccruInterest(totalAccruIntr);
                interestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                interestAccrualInfo.setAccrualDailyProvision(provision);
                interestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);
                interestAccrualInfo.setProvisionalAccrualInterest(BigDecimal.ZERO);




                //重新复制计提金额 生成gl时候需要
                interestAccrualInfo.setAccrualDailyProvision(provision);

                //价税分离
                interestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                updateInterestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                PrPenaltyRateTable prPenaltyRateTable = penaltyRateTableService.findByPenaltyId(interestAccrualInfo.getPenaltyTableId(), interestAccrualInfo.getOrganizationId(), interestAccrualInfo.getTenantId());
                if (TransBizConstant.TAX_FLAG_0.equals(prPenaltyRateTable.getTaxFlag())) {
                    //当日计提税金=含税收入金额/（1+税率）*税率计算每日利息的税金
                    BigDecimal taxAmt = provision.multiply(prPenaltyRateTable.getTaxRate()).divide(BigDecimal.ONE.add(prPenaltyRateTable.getTaxRate()), TransBizConstant.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);

                    //计算调整后税金 = 当日计提税金+上日调整金额
                    BigDecimal dailyAdjustTax = interestAccrualInfo.getAccrualDailyTaxAdjustment();
                    if (dailyAdjustTax == null) {
                        dailyAdjustTax = BigDecimal.ZERO;
                    }
                    BigDecimal afterAdjustTax = taxAmt.add(dailyAdjustTax);
                    //计算当日计提税金(保留两位小数)
                    BigDecimal provisionTax = afterAdjustTax.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    //计算当日调整税金 = 每日调整后累计税金-每日计提税金
                    BigDecimal adjustTax = afterAdjustTax.subtract(provisionTax);

                    provisionTax = provisionTax.add(interestAccrualInfo.getProvisionalTaxAmt());
                    //税金总金额
                    BigDecimal totalTax = interestAccrualInfo.getTaxAmt().add(provisionTax).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    updateInterestAccrualInfo.setTaxAmt(totalTax);
                    updateInterestAccrualInfo.setAccrualNewTax(taxAmt);
                    updateInterestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    updateInterestAccrualInfo.setProvisionalTaxAmt(BigDecimal.ZERO);
                    interestAccrualInfo.setTaxAmt(totalTax);
                    interestAccrualInfo.setAccrualNewTax(taxAmt);
                    interestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    interestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    interestAccrualInfo.setProvisionalTaxAmt(BigDecimal.ZERO);
                    TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.generateGlInterfaceForAcccrualTax(businessDate, interestAccrualInfo);
                    intrAccuBean.addTlGlInterfaceInfo(glInterfaceInfo);
                }

                //生成计提gl流水
                TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.generateGlInterfaceForAcccrual(businessDate, interestAccrualInfo);
                if (glInterfaceInfo != null) {
                    intrAccuBean.addTlGlInterfaceInfo(glInterfaceInfo);
                }
                //生成利息计提日志表
                TlInterestAccrualLog tlInterestAccrualLog = generateAccrualLog(interestAccrualInfo, updateInterestAccrualInfo, businessDate);
                intrAccuBean.addTlInterestAccrualLog(tlInterestAccrualLog);

                //罚息复利滚利改造 如果是还款日前一天关闭累计账户，生成罚息复利交易账户
                Date compareDate = DateUtils.addDay(interestAccrualInfo.getPaymentDueDate(), -1);//还款日前一天
                boolean castDay = businessDate.compareTo(compareDate) >= 0;

                if (castDay && TransBizConstant.YES_FLAG.equals(prPenaltyRateTable.getCastPenaltyPerMonth())) {
                    //获取对应的罚息参数 罚息复利按月计息

                    AmLoanMainInfo amLoanMainInfo = dealIntrBean.getLoanMain();
                    AmLoanAccountInfo amLoanAccountInfo = dealIntrBean.getLoanAcct();

                    //关闭利息累计账户
                    interestAccrualStop(updateInterestAccrualInfo);

                    //生成交易账户
                    CastAccountTransactionBean castAccountTransactionBean = accountService.castInterestAccount(amLoanMainInfo, amLoanAccountInfo,
                            interestAccrualInfo, businessDate, true);
                    intrAccuBean.addAccountMainInfo(castAccountTransactionBean.getAmAccountMainInfo());
                    intrAccuBean.addTlTransactionInfo(castAccountTransactionBean.getTlTransactionInfo());
                    intrAccuBean.addTlGlInterfaceInfoList(castAccountTransactionBean.getTlGlInterfaceInfoList());

                    //更新订单
                    AmLoanAccountInfo updateLoanAccount = new AmLoanAccountInfo();
                    updateLoanAccount.setId(amLoanAccountInfo.getId());
                    updateLoanAccount.setTenantId(amLoanAccountInfo.getTenantId());
                    updateLoanAccount.setCustomerId(amLoanAccountInfo.getCustomerId());
                    updateLoanAccount.setCurrBalance(amLoanAccountInfo.getCurrBalance());
                    if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(type)) {
                        updateLoanAccount.setPenaltyBalance(amLoanAccountInfo.getPenaltyBalance());
                    } else {
                        updateLoanAccount.setCompoundBalance(amLoanAccountInfo.getCompoundBalance());
                    }
                    intrAccuBean.setAmLoanAccountInfo(updateLoanAccount);
                }

                intrAccuBean.addInterestAccrualInfo(updateInterestAccrualInfo);

            } else {
                //配合信用花改造 未到起息日临时计提罚息，税金

                //间隔日期
                int elapseDays;

                Date fromDate;    //开始日期
                Date toDate;    //结束日期

                if (accruToDate == null) {//首次计息
                    fromDate = accruFromDate;
                    toDate = accruDay;
                } else {//除首次之后每日计息
                    fromDate = accruToDate;
                    toDate = accruDay;
                }
                elapseDays = DateUtils.getDiffDays(fromDate, toDate);
                if (elapseDays <= 0) {
                    return null;
                }
                BigDecimal interest;

                interest = this.penInterestCalculation(interestAccrualInfo, elapseDays);

                int totalAccruDays = interestAccrualInfo.getAccrualTotalAccruDays() + elapseDays;
                updateInterestAccrualInfo.setAccrualNewFromDate(fromDate);
                updateInterestAccrualInfo.setAccrualNewToDate(toDate);
                updateInterestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                updateInterestAccrualInfo.setAccrualNewDays(elapseDays);
                updateInterestAccrualInfo.setAccrualNewInterest(interest);
                //计算调整后利息 = 当日计提金额+上日调整金额
                BigDecimal dailyAdjustAmt = interestAccrualInfo.getAccrualDailyAdjustment();
                if (dailyAdjustAmt == null) {
                    dailyAdjustAmt = BigDecimal.ZERO;
                }
                BigDecimal afterAdjustAmt = interest.add(dailyAdjustAmt);
                //计算当日计提金额(保留两位小数)
                BigDecimal provision = afterAdjustAmt.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                //计算当日调整 = 每日调整后累计-每日计提
                BigDecimal adjustAmt = afterAdjustAmt.subtract(provision);
                //利息总金额
                BigDecimal totalAccruIntr = interestAccrualInfo.getProvisionalAccrualInterest().add(provision).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                updateInterestAccrualInfo.setProvisionalAccrualInterest(totalAccruIntr);
                updateInterestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                updateInterestAccrualInfo.setAccrualDailyProvision(provision);
                updateInterestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);

                interestAccrualInfo.setProvisionalAccrualInterest(totalAccruIntr);
                interestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                interestAccrualInfo.setAccrualDailyProvision(provision);
                interestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);

                //重新复制计提金额 生成gl时候需要
                interestAccrualInfo.setAccrualDailyProvision(provision);

                //价税分离
                interestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                updateInterestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                PrPenaltyRateTable prPenaltyRateTable = penaltyRateTableService.findByPenaltyId(interestAccrualInfo.getPenaltyTableId(), interestAccrualInfo.getOrganizationId(), interestAccrualInfo.getTenantId());
                if (TransBizConstant.TAX_FLAG_0.equals(prPenaltyRateTable.getTaxFlag())) {
                    //当日计提税金=含税收入金额/（1+税率）*税率计算每日利息的税金
                    BigDecimal taxAmt = provision.multiply(prPenaltyRateTable.getTaxRate()).divide(BigDecimal.ONE.add(prPenaltyRateTable.getTaxRate()), TransBizConstant.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);

                    //计算调整后税金 = 当日计提税金+上日调整金额
                    BigDecimal dailyAdjustTax = interestAccrualInfo.getAccrualDailyTaxAdjustment();
                    if (dailyAdjustTax == null) {
                        dailyAdjustTax = BigDecimal.ZERO;
                    }
                    BigDecimal afterAdjustTax = taxAmt.add(dailyAdjustTax);
                    //计算当日计提税金(保留两位小数)
                    BigDecimal provisionTax = afterAdjustTax.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    //计算当日调整税金 = 每日调整后累计税金-每日计提税金
                    BigDecimal adjustTax = afterAdjustTax.subtract(provisionTax);
                    //税金总金额
                    BigDecimal totalTax = interestAccrualInfo.getProvisionalTaxAmt().add(provisionTax).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    updateInterestAccrualInfo.setProvisionalTaxAmt(totalTax);
                    updateInterestAccrualInfo.setAccrualNewTax(taxAmt);
                    updateInterestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setProvisionalTaxAmt(totalTax);
                    interestAccrualInfo.setAccrualNewTax(taxAmt);
                    interestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    interestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                }

                intrAccuBean.addInterestAccrualInfo(updateInterestAccrualInfo);

            }
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(type)) {//利息计提
            if (accruDay.compareTo(intrStartDate) >= 0) {
                //利息
                //间隔日期
                int elapseDays;
                Date fromDate;    //开始日期
                Date toDate;    //结束日期
                if (accruToDate == null) {//首次计息
                    fromDate = accruFromDate;
                    toDate = accruDay;
                } else {//除首次之后每日计息
                    fromDate = accruToDate;
                    toDate = accruDay;
                }
                elapseDays = DateUtils.getDiffDays(fromDate, toDate);
                if (elapseDays <= 0) {
                    return null;
                }

                Date paymentDueDate = interestAccrualInfo.getPaymentDueDate();//还款日
                Date compareDate = DateUtils.addDay(paymentDueDate, -1);//还款日前一天

                PrInterestTable prInterestTable = interestTableService.findInterestByInterestId(interestAccrualInfo.getInterestTableId(), interestAccrualInfo.getTenantId());

                //是否已到抛账日 最后一个计息日
                // 还款日前一天抛帐
                boolean castDay = businessDate.compareTo(compareDate) >= 0;
                String castTime = prInterestTable.getCastTime();
                //还款日当天抛帐
                if (TransBizConstant.CAST_TIME_1.equals(castTime)) {
                    castDay = businessDate.compareTo(paymentDueDate) >= 0;
                }

                //还款日前一天钆差
                boolean cutOffIntrDay = businessDate.compareTo(compareDate) >= 0;


                //计算利息
                BigDecimal interest = this.interestCalculation(interestAccrualInfo, elapseDays, cutOffIntrDay);

                //计算总利息金额
                int totalAccruDays = interestAccrualInfo.getAccrualTotalAccruDays() + elapseDays;
                updateInterestAccrualInfo.setAccrualNewFromDate(fromDate);
                updateInterestAccrualInfo.setAccrualNewToDate(toDate);
                updateInterestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                updateInterestAccrualInfo.setAccrualNewDays(elapseDays);
                interestAccrualInfo.setAccrualNewFromDate(fromDate);
                interestAccrualInfo.setAccrualNewToDate(toDate);
                interestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                interestAccrualInfo.setAccrualNewDays(elapseDays);

                updateInterestAccrualInfo.setAccrualNewInterest(interest);
                interestAccrualInfo.setAccrualNewInterest(interest);
                //计算调整后利息 = 当日计提金额+上日调整金额
                BigDecimal dailyAdjustAmt = interestAccrualInfo.getAccrualDailyAdjustment();
                if (dailyAdjustAmt == null) {
                    dailyAdjustAmt = BigDecimal.ZERO;
                }
                BigDecimal afterAdjustAmt = interest.add(dailyAdjustAmt);
                //计算当日计提金额(保留两位小数)
                BigDecimal provision = afterAdjustAmt.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                //计算当日调整 = 每日调整后累计-每日计提
                BigDecimal adjustAmt = afterAdjustAmt.subtract(provision);

                provision = provision.add(interestAccrualInfo.getProvisionalAccrualInterest());

                //总利息金额
                BigDecimal totalAccruIntr = interestAccrualInfo.getAccrualTotalAccruInterest();
                if (interestAccrualInfo.getMaxInterest().compareTo(totalAccruIntr) > 0) {
                    totalAccruIntr = totalAccruIntr.add(provision).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                } else {
                    provision = BigDecimal.ZERO;
                }

                updateInterestAccrualInfo.setAccrualTotalAccruInterest(totalAccruIntr);
                updateInterestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                updateInterestAccrualInfo.setAccrualDailyProvision(provision);
                updateInterestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);
                updateInterestAccrualInfo.setProvisionalAccrualInterest(BigDecimal.ZERO);
                interestAccrualInfo.setAccrualTotalAccruInterest(totalAccruIntr);
                interestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                interestAccrualInfo.setAccrualDailyProvision(provision);
                interestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);
                interestAccrualInfo.setProvisionalAccrualInterest(BigDecimal.ZERO);


                //价税分离
                interestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                updateInterestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                if (TransBizConstant.TAX_FLAG_0.equals(prInterestTable.getTaxFlag())) {
                    //当日计提税金=含税收入金额/（1+税率）*税率计算每日利息的税金
                    BigDecimal taxAmt = provision.multiply(prInterestTable.getTaxRate()).divide(BigDecimal.ONE.add(prInterestTable.getTaxRate()), TransBizConstant.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);

                    //计算调整后税金 = 当日计提税金+上日调整金额
                    BigDecimal dailyAdjustTax = interestAccrualInfo.getAccrualDailyTaxAdjustment();
                    if (dailyAdjustTax == null) {
                        dailyAdjustTax = BigDecimal.ZERO;
                    }
                    BigDecimal afterAdjustTax = taxAmt.add(dailyAdjustTax);
                    //计算当日计提税金(保留两位小数)
                    BigDecimal provisionTax = afterAdjustTax.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    //计算当日调整税金 = 每日调整后累计税金-每日计提税金
                    BigDecimal adjustTax = afterAdjustTax.subtract(provisionTax);

                    provisionTax = provisionTax.add(interestAccrualInfo.getProvisionalTaxAmt());
                    //税金总金额
                    BigDecimal totalTax = interestAccrualInfo.getTaxAmt().add(provisionTax).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    updateInterestAccrualInfo.setTaxAmt(totalTax);
                    updateInterestAccrualInfo.setAccrualNewTax(taxAmt);
                    updateInterestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    updateInterestAccrualInfo.setProvisionalTaxAmt(BigDecimal.ZERO);
                    interestAccrualInfo.setTaxAmt(totalTax);
                    interestAccrualInfo.setAccrualNewTax(taxAmt);
                    interestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    interestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    interestAccrualInfo.setProvisionalTaxAmt(BigDecimal.ZERO);
                    TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.generateGlInterfaceForAcccrualTax(businessDate, interestAccrualInfo);
                    intrAccuBean.addTlGlInterfaceInfo(glInterfaceInfo);
                }

                //生成计提gl流水
                TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.generateGlInterfaceForAcccrual(businessDate, interestAccrualInfo);
                if (glInterfaceInfo != null) {
                    intrAccuBean.addTlGlInterfaceInfo(glInterfaceInfo);
                }
                //生成利息计提日志表
                TlInterestAccrualLog tlInterestAccrualLog = generateAccrualLog(interestAccrualInfo, updateInterestAccrualInfo, businessDate);
                intrAccuBean.addTlInterestAccrualLog(tlInterestAccrualLog);
                //还款日前一天  抛出利息交易账户
                if (castDay) {
                    //如果是最后一天(还款日前一天)，停止计息账户，抛出相同金额的利息交易账户

                    //关闭利息累计账户
                    interestAccrualStop(updateInterestAccrualInfo);

                    //查询订单
                    AmLoanMainInfo amLoanMainInfo = dealIntrBean.getLoanMain();

                    AmLoanAccountInfo amLoanAccountInfo = dealIntrBean.getLoanAcct();
                    //生成利息交易账户
                    CastAccountTransactionBean castAccountTransactionBean = accountService.castInterestAccount(amLoanMainInfo, amLoanAccountInfo,
                            interestAccrualInfo, businessDate, true);
                    intrAccuBean.addAccountMainInfo(castAccountTransactionBean.getAmAccountMainInfo());
                    intrAccuBean.addTlTransactionInfo(castAccountTransactionBean.getTlTransactionInfo());
                    intrAccuBean.addTlGlInterfaceInfoList(castAccountTransactionBean.getTlGlInterfaceInfoList());


                    //查询所有状态正常停息的累计账户，进行抛帐
                    List<AmInterestAccrualInfo> accrualInfoList = dealIntrBean.getStopAccuAcctList();
                    if (CollectionUtils.isNotEmpty(accrualInfoList)) {
                        for (AmInterestAccrualInfo stopAccuAcct : accrualInfoList) {
                            IntrAccuBean stopAcctuBean = this.castAcct(stopAccuAcct, amLoanMainInfo, amLoanAccountInfo, businessDate);
                            stopAcctuBean.getInterestAccrualInfoList().forEach(intrAccuBean::addInterestAccrualInfo);
                            stopAcctuBean.getAccountMainInfoList().forEach(intrAccuBean::addAccountMainInfo);
                            stopAcctuBean.getTransactionInfoList().forEach(intrAccuBean::addTlTransactionInfo);
                            stopAcctuBean.getTlGlInterfaceInfoList().forEach(intrAccuBean::addTlGlInterfaceInfo);
                        }
                    }

                    //更新订单
                    AmLoanAccountInfo updateLoanAccount = new AmLoanAccountInfo();
                    updateLoanAccount.setId(amLoanAccountInfo.getId());
                    updateLoanAccount.setTenantId(amLoanAccountInfo.getTenantId());
                    updateLoanAccount.setCustomerId(amLoanAccountInfo.getCustomerId());
                    updateLoanAccount.setCurrBalance(amLoanAccountInfo.getCurrBalance());
                    updateLoanAccount.setInterestBalance(amLoanAccountInfo.getInterestBalance());
                    intrAccuBean.setAmLoanAccountInfo(updateLoanAccount);
                }
                intrAccuBean.addInterestAccrualInfo(updateInterestAccrualInfo);
            } else {
                //配合信用花改造 未到起息日临时计提利息，税金

                //利息
                //间隔日期
                int elapseDays;
                Date fromDate;    //开始日期
                Date toDate;    //结束日期
                if (accruToDate == null) {//首次计息
                    fromDate = accruFromDate;
                    toDate = accruDay;
                } else {//除首次之后每日计息
                    fromDate = accruToDate;
                    toDate = accruDay;
                }
                elapseDays = DateUtils.getDiffDays(fromDate, toDate);
                if (elapseDays <= 0) {
                    return null;
                }


                //计算利息
                BigDecimal interest = this.interestCalculation(interestAccrualInfo, elapseDays, false);

                //计算总利息金额
                int totalAccruDays = interestAccrualInfo.getAccrualTotalAccruDays() + elapseDays;
                updateInterestAccrualInfo.setAccrualNewFromDate(fromDate);
                updateInterestAccrualInfo.setAccrualNewToDate(toDate);
                updateInterestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                updateInterestAccrualInfo.setAccrualNewDays(elapseDays);
                interestAccrualInfo.setAccrualNewFromDate(fromDate);
                interestAccrualInfo.setAccrualNewToDate(toDate);
                interestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                interestAccrualInfo.setAccrualNewDays(elapseDays);


                updateInterestAccrualInfo.setAccrualNewInterest(interest);
                //计算调整后利息 = 当日计提金额+上日调整金额
                BigDecimal dailyAdjustAmt = interestAccrualInfo.getAccrualDailyAdjustment();
                if (dailyAdjustAmt == null) {
                    dailyAdjustAmt = BigDecimal.ZERO;
                }
                BigDecimal afterAdjustAmt = interest.add(dailyAdjustAmt);
                //计算当日计提金额(保留两位小数)
                BigDecimal provision = afterAdjustAmt.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                //计算当日调整 = 每日调整后累计-每日计提
                BigDecimal adjustAmt = afterAdjustAmt.subtract(provision);
                //总利息金额
                BigDecimal totalAccruIntr = interestAccrualInfo.getProvisionalAccrualInterest();
                if (interestAccrualInfo.getMaxInterest().compareTo(totalAccruIntr) > 0) {
                    totalAccruIntr = totalAccruIntr.add(provision).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                } else {
                    provision = BigDecimal.ZERO;
                }

                updateInterestAccrualInfo.setProvisionalAccrualInterest(totalAccruIntr);
                updateInterestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                updateInterestAccrualInfo.setAccrualDailyProvision(provision);
                updateInterestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);
                interestAccrualInfo.setProvisionalAccrualInterest(totalAccruIntr);
                interestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                interestAccrualInfo.setAccrualDailyProvision(provision);
                interestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);

                //价税分离
                PrInterestTable prInterestTable = interestTableService.findInterestByInterestId(interestAccrualInfo.getInterestTableId(), interestAccrualInfo.getTenantId());

                interestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                updateInterestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                if (TransBizConstant.TAX_FLAG_0.equals(prInterestTable.getTaxFlag())) {
                    //当日计提税金=含税收入金额/（1+税率）*税率计算每日利息的税金
                    BigDecimal taxAmt = provision.multiply(prInterestTable.getTaxRate()).divide(BigDecimal.ONE.add(prInterestTable.getTaxRate()), TransBizConstant.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);

                    //计算调整后税金 = 当日计提税金+上日调整金额
                    BigDecimal dailyAdjustTax = interestAccrualInfo.getAccrualDailyTaxAdjustment();
                    if (dailyAdjustTax == null) {
                        dailyAdjustTax = BigDecimal.ZERO;
                    }
                    BigDecimal afterAdjustTax = taxAmt.add(dailyAdjustTax);
                    //计算当日计提税金(保留两位小数)
                    BigDecimal provisionTax = afterAdjustTax.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    //计算当日调整税金 = 每日调整后累计税金-每日计提税金
                    BigDecimal adjustTax = afterAdjustTax.subtract(provisionTax);
                    //税金总金额
                    BigDecimal totalTax = interestAccrualInfo.getProvisionalTaxAmt().add(provisionTax).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    updateInterestAccrualInfo.setProvisionalTaxAmt(totalTax);
                    updateInterestAccrualInfo.setAccrualNewTax(taxAmt);
                    updateInterestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setProvisionalTaxAmt(totalTax);
                    interestAccrualInfo.setAccrualNewTax(taxAmt);
                    interestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    interestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                }

                intrAccuBean.addInterestAccrualInfo(updateInterestAccrualInfo);
            }
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_70.equals(type)) {//贴息利息计提
            if (accruDay.compareTo(intrStartDate) >= 0) {
                //利息
                //间隔日期
                int elapseDays;
                Date fromDate;    //开始日期
                Date toDate;    //结束日期
                if (accruToDate == null) {//首次计息
                    fromDate = accruFromDate;
                    toDate = accruDay;
                } else {//除首次之后每日计息
                    fromDate = accruToDate;
                    toDate = accruDay;
                }
                elapseDays = DateUtils.getDiffDays(fromDate, toDate);
                if (elapseDays <= 0) {
                    return null;
                }

                Date paymentDueDate = interestAccrualInfo.getPaymentDueDate();//还款日
                Date compareDate = DateUtils.addDay(paymentDueDate, -1);//还款日前一天

                //是否已到抛账日 最后一个计息日  还款日前一天
                boolean lastAccrualDay = businessDate.compareTo(compareDate) >= 0;

                //计算利息
                BigDecimal interest = this.interestCalculation(interestAccrualInfo, elapseDays, lastAccrualDay);

                //计算总利息金额
                int totalAccruDays = interestAccrualInfo.getAccrualTotalAccruDays() + elapseDays;
                updateInterestAccrualInfo.setAccrualNewFromDate(fromDate);
                updateInterestAccrualInfo.setAccrualNewToDate(toDate);
                updateInterestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                updateInterestAccrualInfo.setAccrualNewDays(elapseDays);
                interestAccrualInfo.setAccrualNewFromDate(fromDate);
                interestAccrualInfo.setAccrualNewToDate(toDate);
                interestAccrualInfo.setAccrualTotalAccruDays(totalAccruDays);
                interestAccrualInfo.setAccrualNewDays(elapseDays);

                updateInterestAccrualInfo.setAccrualNewInterest(interest);
                interestAccrualInfo.setAccrualNewInterest(interest);
                //计算调整后利息 = 当日计提金额+上日调整金额
                BigDecimal dailyAdjustAmt = interestAccrualInfo.getAccrualDailyAdjustment();
                if (dailyAdjustAmt == null) {
                    dailyAdjustAmt = BigDecimal.ZERO;
                }
                BigDecimal afterAdjustAmt = interest.add(dailyAdjustAmt);
                //计算当日计提金额(保留两位小数)
                BigDecimal provision = afterAdjustAmt.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                //计算当日调整 = 每日调整后累计-每日计提
                BigDecimal adjustAmt = afterAdjustAmt.subtract(provision);
                //总利息金额
                BigDecimal totalAccruIntr = interestAccrualInfo.getAccrualTotalAccruInterest();
                if (interestAccrualInfo.getMaxInterest().compareTo(totalAccruIntr) > 0) {
                    totalAccruIntr = totalAccruIntr.add(provision).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                } else {
                    provision = BigDecimal.ZERO;
                }

                updateInterestAccrualInfo.setAccrualTotalAccruInterest(totalAccruIntr);
                updateInterestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                updateInterestAccrualInfo.setAccrualDailyProvision(provision);
                updateInterestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);
                interestAccrualInfo.setAccrualTotalAccruInterest(totalAccruIntr);
                interestAccrualInfo.setAccrualDailyAfterAdjustment(afterAdjustAmt);
                interestAccrualInfo.setAccrualDailyProvision(provision);
                interestAccrualInfo.setAccrualDailyAdjustment(adjustAmt);


                //价税分离
                String taxFlag = null;
                BigDecimal taxRate = null;
                //查询订单
                AmLoanMainInfo amLoanMainInfo = dealIntrBean.getLoanMain();
                if (TransBizConstant.WAIVE_TYPE_1.equals(amLoanMainInfo.getWaiveType())) {
                    PrWaiveInterestTable prWaiveInterestTable = prWaiveInterestTableService.findWaiveInterestByInterestId(interestAccrualInfo.getInterestTableId(), interestAccrualInfo.getTenantId());
                    taxFlag = prWaiveInterestTable.getTaxFlag();
                    taxRate = prWaiveInterestTable.getTaxRate();
                } else {
                    PrInterestTable prInterestTable = interestTableService.findInterestByInterestId(interestAccrualInfo.getInterestTableId(), interestAccrualInfo.getTenantId());
                    taxFlag = prInterestTable.getTaxFlag();
                    taxRate = prInterestTable.getTaxRate();
                }

                interestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                updateInterestAccrualInfo.setAccrualDailyTaxProvision(BigDecimal.ZERO);
                if (TransBizConstant.TAX_FLAG_0.equals(taxFlag)) {
                    //当日计提税金=含税收入金额/（1+税率）*税率计算每日利息的税金
                    BigDecimal taxAmt = provision.multiply(taxRate).divide(BigDecimal.ONE.add(taxRate), TransBizConstant.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);

                    //计算调整后税金 = 当日计提税金+上日调整金额
                    BigDecimal dailyAdjustTax = interestAccrualInfo.getAccrualDailyTaxAdjustment();
                    if (dailyAdjustTax == null) {
                        dailyAdjustTax = BigDecimal.ZERO;
                    }
                    BigDecimal afterAdjustTax = taxAmt.add(dailyAdjustTax);
                    //计算当日计提税金(保留两位小数)
                    BigDecimal provisionTax = afterAdjustTax.setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    //计算当日调整税金 = 每日调整后累计税金-每日计提税金
                    BigDecimal adjustTax = afterAdjustTax.subtract(provisionTax);
                    //税金总金额
                    BigDecimal totalTax = interestAccrualInfo.getTaxAmt().add(provisionTax).setScale(TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
                    updateInterestAccrualInfo.setTaxAmt(totalTax);
                    updateInterestAccrualInfo.setAccrualNewTax(taxAmt);
                    updateInterestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    updateInterestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setTaxAmt(totalTax);
                    interestAccrualInfo.setAccrualNewTax(taxAmt);
                    interestAccrualInfo.setAccrualDailyTaxAfterAdjustment(afterAdjustTax);
                    interestAccrualInfo.setAccrualDailyTaxAdjustment(adjustTax);
                    interestAccrualInfo.setAccrualDailyTaxProvision(provisionTax);
                    TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.generateGlInterfaceForAcccrualTax(businessDate, interestAccrualInfo);
                    intrAccuBean.addTlGlInterfaceInfo(glInterfaceInfo);
                }

                //生成计提gl流水
                TlGlInterfaceInfo glInterfaceInfo = glInterfaceService.generateGlInterfaceForAcccrual(businessDate, interestAccrualInfo);
                if (glInterfaceInfo != null) {
                    intrAccuBean.addTlGlInterfaceInfo(glInterfaceInfo);
                }
                //生成利息计提日志表
                TlInterestAccrualLog tlInterestAccrualLog = generateAccrualLog(interestAccrualInfo, updateInterestAccrualInfo, businessDate);
                intrAccuBean.addTlInterestAccrualLog(tlInterestAccrualLog);
                //还款日前一天  抛出利息交易账户
                if (lastAccrualDay) {
                    //如果是最后一天(还款日前一天)，停止计息账户，抛出相同金额的利息交易账户

                    //关闭利息累计账户
                    interestAccrualStop(updateInterestAccrualInfo);

                    AmLoanAccountInfo amLoanAccountInfo = dealIntrBean.getLoanAcct();
                    //生成利息交易账户
                    CastAccountTransactionBean castAccountTransactionBean = accountService.castWaiveInterestAccount(amLoanMainInfo, amLoanAccountInfo,
                            interestAccrualInfo, businessDate);
                    intrAccuBean.addAccountMainInfo(castAccountTransactionBean.getAmAccountMainInfo());
                    intrAccuBean.addTlTransactionInfo(castAccountTransactionBean.getTlTransactionInfo());
                    intrAccuBean.addTlGlInterfaceInfoList(castAccountTransactionBean.getTlGlInterfaceInfoList());

                }
                intrAccuBean.addInterestAccrualInfo(updateInterestAccrualInfo);
            }
        }
        return intrAccuBean;
    }

    /**
     * 停止计息累计账户，关闭原累计交易账户，生成交易账户
     *
     * @param interestAccrualInfo
     * @param businessDate
     * @return
     * @throws TxnException
     */
    public IntrAccuBean castAcct(AmInterestAccrualInfo interestAccrualInfo, AmLoanMainInfo loanMain, AmLoanAccountInfo loanAcct, Date businessDate) throws TxnException {

        logger.debug("已停止计息,id:{},accountId:{},结息标志:{},计息日期:{}，抛出交易账户", interestAccrualInfo.getId(), interestAccrualInfo.getAccountId(), interestAccrualInfo.getStopAccrualFlag(), interestAccrualInfo.getAccrualNewToDate());

        IntrAccuBean intrAccuBean = new IntrAccuBean();
        //更新累计交易
        AmInterestAccrualInfo updateInterestAccrualInfo = new AmInterestAccrualInfo();
        updateInterestAccrualInfo.setId(interestAccrualInfo.getId());
        updateInterestAccrualInfo.setCustomerId(interestAccrualInfo.getCustomerId());
        updateInterestAccrualInfo.setTenantId(interestAccrualInfo.getTenantId());
        updateInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_8);
        intrAccuBean.addInterestAccrualInfo(updateInterestAccrualInfo);

        //生成利息交易账户
        CastAccountTransactionBean castAccountTransactionBean = accountService.castInterestAccount(loanMain, loanAcct,
                interestAccrualInfo, businessDate, true);
        intrAccuBean.addAccountMainInfo(castAccountTransactionBean.getAmAccountMainInfo());
        intrAccuBean.addTlTransactionInfo(castAccountTransactionBean.getTlTransactionInfo());
        intrAccuBean.addTlGlInterfaceInfoList(castAccountTransactionBean.getTlGlInterfaceInfoList());
        return intrAccuBean;
    }

    /**
     * 生成利息计提日志表
     *
     * @param amInterestAccrualInfo     原累计账户
     * @param updateInterestAccrualInfo 更新累计账户
     * @param accruDate                 计提日期
     * @return
     */
    private TlInterestAccrualLog generateAccrualLog(AmInterestAccrualInfo amInterestAccrualInfo, AmInterestAccrualInfo updateInterestAccrualInfo, Date accruDate) throws TxnBizException {
        TlInterestAccrualLog tlInterestAccrualLog = new TlInterestAccrualLog();
        BeanMapping.copy(amInterestAccrualInfo, tlInterestAccrualLog);
        try {
            tlInterestAccrualLog.setId(segmentService.getId(TransBizConstant.TL_INTEREST_ACCRUAL_LOG_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        tlInterestAccrualLog.setAccrualDate(accruDate);
        tlInterestAccrualLog.setLastTotalAmount(amInterestAccrualInfo.getAccrualTotalAccruInterest());
        tlInterestAccrualLog.setCurrentTotalAmount(updateInterestAccrualInfo.getAccrualTotalAccruInterest());
        tlInterestAccrualLog.setAccrualProvision(updateInterestAccrualInfo.getAccrualDailyProvision());
        tlInterestAccrualLog.setAccrualAdjustment(updateInterestAccrualInfo.getAccrualDailyAdjustment());
        tlInterestAccrualLog.setTaxAmtProvision(updateInterestAccrualInfo.getAccrualDailyTaxProvision());
        tlInterestAccrualLog.setTaxExcludedAccrualProvision(updateInterestAccrualInfo.getAccrualDailyProvision().subtract(updateInterestAccrualInfo.getAccrualDailyTaxProvision()));
        tlInterestAccrualLog.setCreateTime(null);
        tlInterestAccrualLog.setAccountType(amInterestAccrualInfo.getAccountType());
        tlInterestAccrualLog.setDailyRate(amInterestAccrualInfo.getAccrualDailyRate());
        tlInterestAccrualLog.setCurrentTotalTax(amInterestAccrualInfo.getTaxAmt());
        tlInterestAccrualLog.setAccrualTaxAdjustment(amInterestAccrualInfo.getAccrualDailyTaxAdjustment());
        return tlInterestAccrualLog;
    }


    /**
     * 每日计息处理
     * 计算利息
     *
     * @param intrAcct
     * @param elapseDays
     * @param lastAccrualDay
     * @return
     */
    private BigDecimal interestCalculation(AmInterestAccrualInfo intrAcct, int elapseDays, boolean lastAccrualDay) {
        logger.debug("计息开始 id:{},accountId:{}", intrAcct.getId(), intrAcct.getAccountId());
        //如果大于等于还款日，则直接返回
        BigDecimal accuIntrAmnt = intrAcct.getAccrualBaseAmount();// 计息金额
        BigDecimal totalAccruIntr = intrAcct.getAccrualTotalAccruInterest(); //总利息累计金额
        BigDecimal calculateInt = BigDecimal.ZERO.setScale(TransBizConstant.BIGDECIMAL_SCALE_7); //本天利息金额

        if (accuIntrAmnt.compareTo(BigDecimal.ZERO) <= 0) {
            return calculateInt;// 如果计息金额<=0，则利息值直接返回0
        }

        BigDecimal dailyRate = intrAcct.getAccrualDailyRate();
        logger.debug("id:{},accountId:{},日利率={}", intrAcct.getId(), intrAcct.getAccountId(), dailyRate);

        //获取利息累计账户对应本金交易账户
        BigDecimal interestAmt = intrAcct.getMaxInterest(); //计划中利息金额

        //固定利率计息
        calculateInt = accuIntrAmnt.multiply(dailyRate).multiply(BigDecimal.valueOf(elapseDays)).setScale(TransBizConstant.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);//当前总利息-已累计利息

        BigDecimal tmpTotalAccruIntr = totalAccruIntr.add(calculateInt);

        boolean overMax = tmpTotalAccruIntr.compareTo(interestAmt) > 0;//总累计金额超过利息最大值
        //计息最后一天（还款日前一天) or 总累计金额超过利息最大值
        if (lastAccrualDay || overMax) {
            calculateInt = interestAmt.subtract(totalAccruIntr);
        }
        logger.debug("id:{},accountId:{},计算出利息金额={}", intrAcct.getId(), intrAcct.getAccountId(), calculateInt);
        return calculateInt;
    }


    /**
     * 累计罚息计算
     *
     * @param interestAccrualInfo
     * @param elapseDays
     * @return
     */
    private BigDecimal penInterestCalculation(AmInterestAccrualInfo interestAccrualInfo, int elapseDays) {
        //查询罚息参数表信息

        BigDecimal calculateAmt = interestAccrualInfo.getAccrualBaseAmount();// 计息金额

        BigDecimal calculateInt = BigDecimal.ZERO.setScale(TransBizConstant.BIGDECIMAL_SCALE_7);

        if (calculateAmt.compareTo(BigDecimal.ZERO) <= 0) {
            return calculateInt;// 如果计息金额<=0，则利息值直接返回0
        }

        calculateInt = calculateAmt.multiply(interestAccrualInfo.getAccrualDailyRate()).multiply(BigDecimal.valueOf(elapseDays))
                .setScale(TransBizConstant.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);// 四舍五入，保留7为小数

        return calculateInt;
    }


    /**
     * 停止计息
     *
     * @param updateInterestAccrualInfo
     * @return
     */
    private void interestAccrualStop(AmInterestAccrualInfo updateInterestAccrualInfo) {
        updateInterestAccrualInfo.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_1);
        updateInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_8);
    }
}
